package com.yaDuo.common.base

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.yaDuo.common.extra.parseErrorString
import com.yaDuo.common.request.CategoryDataBean
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch

/**
 * @author YaDuo
 * time 2025-01-03 12:24
 */
open class BaseViewModel : ViewModel() {
    private val errorMsgLiveData by lazy { MutableLiveData<String>() }
    private val showUCategoryData by lazy { MutableLiveData<CategoryDataBean>() }


    fun show(strMessage: String = "正在请求数据") {
//        val showBean = showUCategoryData.value ?: CategoryDataBean(strMessage, true)
//        showBean.isShow = true
//        showBean.msg = strMessage
//        showUCategoryData.postValue(showBean)
    }

    fun hide() {
//        val showBean = showUCategoryData.value ?: CategoryDataBean("", true)
//        showBean.isShow = false
//        showUCategoryData.postValue(showBean)
    }

    /**
     * 会在组件销毁的时候回调
     */
    override fun onCleared() {
        viewModelScope.cancel()
    }

    private fun <T> Flow<T>.flowOnIOAndCatch(): Flow<T> = flowOnIOAndCatch(errorMsgLiveData)

    private fun <T> Flow<T>.onStartAndShow(strMessage: String = "正在请求数据"): Flow<T> = onStart {
        show()
    }

    private fun <T> Flow<T>.onCompletionAndHide(): Flow<T> = onCompletion {
        hide()
    }

    private suspend fun <T> Flow<T>.onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect() {
        onStartAndShow().onCompletionAndHide().flowOnIOAndCatch().collect()//这里，开始结束全放在异步里面处理
    }

    fun <T> flowAsyncWorkOnViewModelScopeLaunch(flowAsyncWork: suspend () -> Flow<T>) {
        viewModelScope.launch {
            flowAsyncWork.invoke().onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect()
        }
    }

    private fun <T> Flow<T>.flowOnIOAndCatch(errorMsgLiveData: MutableLiveData<String>? = null): Flow<T> =
        flowOn(Dispatchers.IO)
            .catch {
                it.printStackTrace()
                errorMsgLiveData?.value = it.parseErrorString()
            }

}